package com.fpx.metadata.service.handle;

import com.fpx.metadata.bean.po.Columns;
import com.fpx.metadata.bean.po.DbInfo;
import com.fpx.metadata.bean.po.Schemata;
import com.fpx.metadata.bean.po.Tables;
import com.fpx.metadata.service.ColumnsService;
import com.fpx.metadata.service.SchemataService;
import com.fpx.metadata.service.TablesService;
import com.fpx.metadata.tool.DynamicDataSourceManager;
import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author caowei
 */
@Log4j2
@Service
public class MysqlMetaDataHandle {

    @Autowired
    private DynamicDataSourceManager dynamicDataSourceManager;
    @Autowired
    private SchemataService schemataService;
    @Autowired
    private TablesService tablesService;
    @Autowired
    private ColumnsService columnsService;

    @Transactional(rollbackFor = Exception.class)
    @Async
    public void buildMetaDataInfo(DbInfo dbInfo) throws Exception {
        //1.获取数据源
        JdbcTemplate jdbcTemplate = dynamicDataSourceManager.getDataSourcePoolByDatabase(dbInfo);
        //3.保存到库信息
        List<Schemata> schematas = jdbcTemplate.query("select * from information_schema.schemata", rs -> {
            List<Schemata> schematasResult = Lists.newArrayList();
            while (rs.next()) {
                Schemata schemata = new Schemata();
                schemata.setHost(dbInfo.getHost());
                schemata.setSchemaName(rs.getString("schema_name"));
                schemata.setDefaultCharacterSetName(rs.getString("default_character_set_name"));
                schemata.setDefaultCollationName(rs.getString("default_collation_name"));
                schematasResult.add(schemata);
            }
            return schematasResult;
        });

        assert schematas != null;
        for (Schemata schemata : schematas) {
            assert schemataService.saveSelect(schemata) > 0;
        }
        log.info("库信息 ： {}", schematas);

        //4.保存表信息
        List<Tables> tablesList = jdbcTemplate.query("select * from information_schema.tables", rs -> {
            List<Tables> tablesResult = Lists.newArrayList();
            while (rs.next()) {
                Tables tables = new Tables();
                tables.setTableSchema(rs.getString("TABLE_SCHEMA"));
                Schemata schemataResult = schematas.stream()
                        .filter(schemata -> schemata.getSchemaName().equals(tables.getTableSchema()))
                        .findFirst()
                        .orElse(null);
                tables.setTableSchemaId(schemataResult == null ? 0L : schemataResult.getId());
                tables.setTableName(rs.getString("TABLE_NAME"));
                tables.setTableType(rs.getString("TABLE_TYPE"));
                tables.setEngine(rs.getString("ENGINE"));
                tables.setCreateTime(rs.getTimestamp("CREATE_TIME"));
                tables.setUpdateTime(rs.getTimestamp("UPDATE_TIME"));
                tables.setTableCollation(rs.getString("TABLE_COLLATION"));
                tables.setTableComment(rs.getString("TABLE_COMMENT"));
                tablesResult.add(tables);
            }
            return tablesResult;
        });
        assert tablesList != null;
        for (Tables tables : tablesList) {
            assert tablesService.saveSelect(tables) > 0;
        }
        log.info("表信息：{}",tablesList);
        //5.保存列信息
        List<Columns> columnsList = jdbcTemplate.query("select * from information_schema.columns", rs -> {
            List<Columns> columnsResult = Lists.newArrayList();
            while (rs.next()) {
                Columns columns = new Columns();
                columns.setTableSchema(rs.getString("TABLE_SCHEMA"));
                columns.setTableName(rs.getString("TABLE_NAME"));
                Tables tables = tablesList.stream()
                        .filter(table -> table.getTableSchema().equals(columns.getTableSchema()) && table.getTableName().equals(columns.getTableName()))
                        .findFirst()
                        .orElse(null);
                columns.setTableId(tables == null ? 0 : tables.getId());
                columns.setColumnName(rs.getString("COLUMN_NAME"));
                columns.setIsNullable(rs.getString("IS_NULLABLE"));
                columns.setDataType(rs.getString("DATA_TYPE"));
                columns.setCharacterSetName(rs.getString("CHARACTER_SET_NAME"));
                columns.setCollationName(rs.getString("COLLATION_NAME"));
                columns.setColumnKey(rs.getString("COLUMN_KEY"));
                columns.setExtra(rs.getString("EXTRA"));
                columns.setColumnComment(rs.getString("COLUMN_COMMENT"));
                columns.setColumnDefault(rs.getString("COLUMN_DEFAULT"));
                columns.setColumnType(rs.getString("COLUMN_TYPE"));
                columnsResult.add(columns);
            }
            return columnsResult;
        });
        assert columnsList != null;
        for (Columns columns : columnsList) {
            assert columnsService.saveSelect(columns) > 0;
        }
        log.info("字段信息：{}", columnsList);
    }
}
